package com.ljx.strategyMode;

import lombok.Data;

/**
 * 策略模式
 * 定义算法族，分别封装起来，让它们之间可以相互替换，此模式的变化独立于算法的使用者
 * 本质：分离算法，选择实现
 *
 * 应用场景：
 * 同一个算法，有很多不同的实现情况。
 * 一个定义了很多行为的类，通过多个if-else语句来选择这些行为的情况
 *
 *
 * 优点：
 * 避免让客户端涉及到重要算法和数据
 * 避免使用难以维护的多重条件选择语句
 * 易扩展
 *
 * 缺点：
 * 判断逻辑在客户端，需求改变时，要更改客户端的程序。
 * 客户端必须知道所有的策略类，并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别，以便适时选择恰当的算法类。
 * 增加了对象的数目
 * 只适合扁平的算法结构
 *
 * 经典案例：
 * JDK Comparable 接口
 *
 * @作者 LJX
 * @日期 2022/12/21 14:02
 */
public class StrategyTest{

    public static void main(String[] args) {
        BasicsZombie bz = new NormalZombie(new NormalMove(), new NormalAttack(), new NormalAppearance());
        bz.showAttack();
        bz.showAppearance();
        bz.showMove();
        bz.showName();
        System.out.println("====================================");
        BasicsZombie sz = new SpecialZombie(new JumpMove(), new ViolenceAttack(), new LimitAppearance());
        sz.showAttack();
        sz.showAppearance();
        sz.showMove();
        sz.showName();

    }

}

/**
 * 僵尸移动方式
 */
interface Move{
    void move();
}

/**
 * 正常移动
 */
class NormalMove implements Move{

    @Override
    public void move() {
        System.out.println("正常移动");
    }
}

/**
 * 跳跃移动
 */
class JumpMove implements Move{

    @Override
    public void move() {
        System.out.println("跳跃移动");
    }
}

/**
 * 僵尸攻击方式
 */
interface Attack{
    void attack();
}

/**
 * 正常攻击
 */
class NormalAttack implements Attack{

    @Override
    public void attack() {
        System.out.println("正常攻击");
    }
}

/**
 * 暴力攻击
 */
class ViolenceAttack implements Attack{

    @Override
    public void attack() {
        System.out.println("暴力攻击");
    }
}

/**
 * 僵尸外观
 */
interface Appearance{
    void appearance();
}

/**
 * 正常外观
 */
class NormalAppearance implements Appearance{

    @Override
    public void appearance() {
        System.out.println("正常外观");
    }
}

/**
 * 限定外观
 */
class LimitAppearance implements Appearance{

    @Override
    public void appearance() {
        System.out.println("限定外观");
    }
}

/**
 * 基础僵尸
 */
@Data
abstract class BasicsZombie{
    Move move;
    Attack attack;
    Appearance appearance;

//    public BasicsZombie(){
//        this.move = new NormalMove();
//        this.attack = new NormalAttack();
//        this.appearance = new NormalAppearance();
//    }

    public BasicsZombie(Move move, Attack attack, Appearance appearance) {
        this.move = move;
        this.attack = attack;
        this.appearance = appearance;
    }

    //展示外观
    abstract public void showAppearance();
    //展示移动
    abstract public void showMove();
    //展示攻击
    abstract public void showAttack();

    public void showName(){
        System.out.println("基础僵尸");
    }

}

@Data
class NormalZombie extends BasicsZombie{
    public NormalZombie(Move move, Attack attack, Appearance appearance) {
        super(move, attack, appearance);
    }

    @Override
    public void showAppearance() {
        super.appearance.appearance();
    }

    @Override
    public void showMove() {
        super.move.move();
    }

    @Override
    public void showAttack() {
        super.attack.attack();
    }

    @Override
    public void showName(){
        System.out.println("正常僵尸");
    }
}

@Data
class SpecialZombie extends BasicsZombie{

    public SpecialZombie(Move move, Attack attack, Appearance appearance) {
        super(move, attack, appearance);
    }

    @Override
    public void showAppearance() {
        super.appearance.appearance();
    }

    @Override
    public void showMove() {
        super.move.move();
    }

    @Override
    public void showAttack() {
        super.attack.attack();
    }

    @Override
    public void showName(){
        System.out.println("特殊僵尸");
    }
}